<?php
//令牌桶算法或简单的计数算法进行限流中间件
declare (strict_types = 1);

namespace app\middleware;
use think\facade\Log;
use think\facade\Queue;
use app\middleware\BaseMiddleware;
use app\service\TokenBucketService;
use app\job\ApiTaskJob;

class TokenBucketMiddleware extends BaseMiddleware{
    /**
     * 处理请求
     *
     * @param \think\Request $request
     * @param \Closure       $next
     * @return Response
     */
    public function handle($request, \Closure $next){

        $ip = $request->ip();
        $result=TokenBucketService::hybridlimiter($ip);
        // if(!$result){
        if(!$result){

            // 限流后将请求放入队列
            $data = [
                'api_url' => $request->url(true),
                'http_method' => $request->method(),
                'request_data' => $request->param(),
                'headers' => $request->header(),
            ];

            //对列名称
            $jobQueueName="apiRunQueue";
            $isPushed=Queue::push(ApiTaskJob::class, $data,$jobQueueName);
            if($isPushed==false){
                Log::error($jobQueueName."创建对列失败:".$data);
            }

            // return $this->return_err(1004,'请求放到对列中了');
            return $this->return_err(1004,'请求过于频繁,请稍后在试!');
        }
        return $next($request);
    }

}
